package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.core.BeanFactory;
import com.example.mapper.UserMapper;
import com.example.plugin.UserPlugin;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * <p>
 * 用户实现类
 * </p>
 *
 * @author: rch
 * @since: 2020-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /**
     * 因为 使用的 mybatis-plus
     * 已经为我们  封装好了  基本的增删查改  service的实现。
     * 如果想要在基本的 增 删  改  逻辑 之前之后切入。 只有重写 这些方法。 具体实现还是调用
     * 原本的 mybatis-plus 帮我们实现 的、  我们的目的是在 之前之后  插入我们的逻辑、
     *
     * 如下新增用户范例
     */
    @Override
    public boolean save(User entity)
    {
        if (!beforeSave(entity)) {
            return  false;
        }

        System.out.println("==UserServiceImpl== 新增用户的操作！  ====");
        if (super.save(entity)) {
            if (!afterSave(entity)){
                return false;
            }
        }

        return true;
    }

    /**
     * 新增用户之前切入插件
     * 通过 从ioc 容器中获取 指定类型的bean 的实例(通过我们定义的插件接口  就可以获取所有我们实现了该插件接口的bean)
     * 然后就可以调用对应的方法
     *
     * 拓展： 这里从容器中获取bean 是可以操作的(可以通过定义一些变量 如果 某个bean 值或者 怎么样，就返回该bean)
     *        这样可以实现， 不是说所有 实现了我们要获取的 插件接口的 实现类  都返回、
     *        甚至 我们还可以 控制返回 实现类的 顺序。 让插件实现类 按顺序执行。
     *
     *        范例中我没有  做这一步。 需要的时候可以加上这个逻辑、
     *
     *
     * @param entity
     * @return
     */
    public boolean beforeSave(User entity)
    {
        Collection<UserPlugin> plugins = BeanFactory.getBeans(UserPlugin.class);

        for (UserPlugin plugin: plugins)
        {
            if ( !plugin.beforeSave(entity))
            {
                return false;
            }
        }

        return true;
    }

    /**
     * 新增用户之后 切入插件
     * @param entity
     * @return
     */
    public boolean afterSave(User entity)
    {
        Collection<UserPlugin> plugins = BeanFactory.getBeans(UserPlugin.class);

        for (UserPlugin plugin: plugins)
        {
            if ( !plugin.afterSave(entity))
            {
                return false;
            }
        }

        return true;
    }
}
